package com.kai.mqtt.protocol;

import io.netty.channel.Channel;
import io.netty.handler.codec.mqtt.MqttMessage;
import io.netty.handler.codec.mqtt.MqttMessageType;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.experimental.FieldDefaults;

import java.util.Objects;

/**
 * @author weijk
 * @since 2024/4/26
 */
public abstract class AbstractProtocol {

    public abstract void process(Channel channel, MqttMessage message);

    @Getter
    @AllArgsConstructor(access = AccessLevel.PRIVATE)
    @FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
    public enum MessageEnum {
        CONNECT(MqttMessageType.CONNECT, Connect.class),
        CONN_ACK(MqttMessageType.CONNACK, null),
        PUBLISH(MqttMessageType.PUBLISH, Publish.class),
        PUB_ACK(MqttMessageType.PUBACK, PubAck.class),
        PUB_REC(MqttMessageType.PUBREC, PubRec.class),
        PUB_REL(MqttMessageType.PUBREL, PubRel.class),
        PUB_COMP(MqttMessageType.PUBCOMP, PubComp.class),
        SUBSCRIBE(MqttMessageType.SUBSCRIBE, Subscribe.class),
        SUB_ACK(MqttMessageType.SUBACK, null),
        UNSUBSCRIBE(MqttMessageType.UNSUBSCRIBE, Unsubscribe.class),
        UNSUB_ACK(MqttMessageType.UNSUBACK, null),
        PING_REQ(MqttMessageType.PINGREQ, PingReq.class),
        PING_RESP(MqttMessageType.PINGRESP, null),
        DISCONNECT(MqttMessageType.DISCONNECT, Disconnect.class),
        AUTH(MqttMessageType.AUTH, null);

        MqttMessageType mqttMessageType;
        Class<? extends AbstractProtocol> clazz;

        public static Class<? extends AbstractProtocol> getClassByMessageType(MqttMessageType mqttMessageType) {
            for (MessageEnum messageEnum : MessageEnum.values()) {
                if (Objects.equals(messageEnum.mqttMessageType, mqttMessageType)) {
                    return messageEnum.clazz;
                }
            }

            return null;
        }
    }
}
